AWS SAMでAWS Lambda関数にAmazon EventBridge Schedulerを設定すると、暗黙的に関連リソースも追加されたので調べてみた

AWS SAMでAWS Lambda関数にAmazon EventBridge Schedulerを設定すると、暗黙的に関連リソースも追加されたので調べてみた

AWS SAMで設定する項目によっては、対象リソースの他にも関連リソースが暗黙的に作成されます。SAMのデプロイ時にこの仕様を知らないとけっこう戸惑うと思うので、EventBridge Schedulerを例にどういった関連リソースが作成されるのか検証します。
Clock Icon2024.10.22

Amazon EventBridge Schedulerの他にもリソースが追加されている?

おのやんです。

みなさん、AWS SAM(以下、SAM)でAWS Lambda(以下、Lambda)を定期実行するAmazon EventBridge (以下、EventBridge) Schedulerを追加した時に、EventBridge Scheduler以外のリソースが追加されてることを不思議に思ったことはありませんか?私はあります。

SAMはAWS CloudFormation(以下、CFn)の拡張であるため、CFnと違ってテンプレートに明示的に記述した以外のリソースも暗黙的に作成してくれます。そのためCFnに慣れた方の中には「このリソース、記述してないけど作成対象に入ってるんだが?」と疑問に思う方もいます。

ということで、今回はLambda関数にEventBridge Schedulerを追加した時に暗黙的に作成されるリソースをまとめてみたいと思います。

公式情報

ドキュメントを確認してみると、SAMのLambda関数のEventsに設定するEventBridgeRuleの詳細には、「AWS::Lambda::Permissionも追加される」と明記してあります。

EventBridgeRule

EventBridgeRule イベントソースタイプを記述するオブジェクト。サーバーレス関数を Amazon EventBridge ルールのターゲットとして設定します。詳細については、「Amazon ユーザーガイド」の「Amazon とは EventBridge」を参照してください。 EventBridge

AWS SAM が を生成する AWS::Events::Rule このイベントタイプが設定されている場合の リソース。 AWS SAM は AWS::Lambda::Permissionリソースも作成します。 これは、 が Lambda を呼びEventBridgeRule出すために必要です。

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-property-function-eventbridgerule.html

またEventBridgeRuleの他にも、Eventsに設定する項目によっては、他のリソースを暗黙的に作成するとのことです。

EventSource

関数をトリガーするイベントのソースを説明するオブジェクトです。各イベントは、1 つのタイプ と、そのタイプに依存する一連のプロパティ で構成されます。各イベントソースのプロパティの詳細については、そのタイプに対応するトピックを参照してください。

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-property-function-eventsource.html

検証

まずは、簡単なSAMテンプレートを用いてLambda関数を作成してみます。こちらは、sam initを実行した時に最初に作成されるLambda関数を元に、Lambda部分のみ残したSAM テンプレートです。

template.yaml
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
  aws-test-sample-app

  Sample SAM Template for aws-test-sample-app

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3
    MemorySize: 128

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn

こちらのテンプレートを、sam buildsam deployコマンドでデプロイします。

そして次に、こちらのテンプレートにEventBridge Schedulerを追加します。

template.yaml
 AWSTemplateFormatVersion: "2010-09-09"
 Transform: AWS::Serverless-2016-10-31
 Description: >
   aws-test-sample-app

   Sample SAM Template for aws-test-sample-app

 # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
   Function:
     Timeout: 3
     MemorySize: 128

 Resources:
   HelloWorldFunction:
     Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
     Properties:
       CodeUri: hello_world/
       Handler: app.lambda_handler
       Runtime: python3.9
       Architectures:
         - x86_64
+      Events:
+        PeriodicSchedule:
+          Type: Schedule
+          Properties:
+            Enabled: true
+            Schedule: !Sub "cron(*/15 * * * ? *)"

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn

この状態でsam buildsam deployを実行して、前回デプロイ時とのリソースの差分を確認します。

EventBridege Scheduler 追加時に作成されるリソース

上記の状態で差分を確認してみると、以下の出力確認できます。これより、SAM経由でLambda関数にEventBridge Schedulerを追加した際に、AWS::Lambda::Permissionリソースも作成されます。

...

Waiting for changeset to be created..

CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation                                     LogicalResourceId                             ResourceType                                  Replacement                                 
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add                                         HelloWorldFunctionPeriodicSchedulePermissio   AWS::Lambda::Permission                       N/A                                         
                                              n                                                                                                                                       
+ Add                                         HelloWorldFunctionPeriodicSchedule            AWS::Events::Rule                             N/A                                         
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

...

追加されるリソースの命名は、出力を確認する限りだと以下のようになっています

  • EventBridgeルール(EventBridge Scheduler)名
    • <Lambda関数名>PeriodicSchedule
  • Lambdaに付与されるリソースベースポリシー
    • <Lambda関数名>PeriodicSchedulePermission

EventBridgeのルールは、SAMテンプレートに記述したようにそのまま設定されています。

eventbridge_rule

デプロイ後は、こちらのようにLambda関数にリソースベースのポリシーステートメントが追加されていることがわかります。これにより、Lambda関数を実行する権限をEventBridgeルールに付与しています。

resource_base_policy_statement

ポリシーステートメントの内容は以下の通りです。

項目
Statement ID aws-test-sample-app-HelloWorldFunctionPeriodicSchedulePermission-<uuid>
Principal events.amazonaws.com
Effect Allow
Action lambda:InvokeFunction
Conditions 以下のJSON
Conditions
{
  "ArnLike": {
    "AWS:SourceArn": "arn:aws:events:ap-northeast-1:<accound_id>:rule/aws-test-sample-app-HelloWorldFunctionPeriodicSched-abcdefghijkl"
  }
}

SAMテンプレートでEventsの項目を設定すると、関連リソースも作成されることがある

今回の検証項目はEventBridge Schedulerでしたが、例えばDynamoDBイベントを設定するとAWS::Lambda::EventSourceMappingリソースを作成するなど、イベントによって作成する関連リソースが異なる点にも注意したいですね。

この仕様は知らないと結構戸惑うと思うので、これを機に意識していただければと思います。では!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.